#include <iostream>
#include <thread>
#include <mutex>
#include <vector>
#include <random>
#include <chrono>
#include <atomic>

class Channel
{
private:
    std::atomic<bool> is_busy{false};
    std::atomic<int> collision_count{0};
    std::mutex cout_mutex;

public:
    bool try_acquire(int node_id)
    {
        bool expected = false;
        if (is_busy.compare_exchange_strong(expected, true))
        {
            return true;
        }
        ++collision_count;
        return false;
    }

    void release()
    {
        is_busy.store(false);
    }

    int get_collision_count() const
    {
        return collision_count.load();
    }

    void log(const std::string &msg)
    {
        std::lock_guard<std::mutex> lock(cout_mutex);
        std::cout << msg << std::endl;
    }
};

class NetworkNode
{
private:
    int id;
    Channel &channel;
    std::atomic<bool> running{true};
    static constexpr int SLOT_TIME = 10;

    int calculate_backoff()
    {
        int k = std::min(channel.get_collision_count(), 10);
        std::random_device rd;
        std::mt19937 gen(rd());
        std::uniform_int_distribution<> dis(0, (1 << k) - 1);
        return dis(gen) * SLOT_TIME;
    }

public:
    NetworkNode(int node_id, Channel &ch) : id(node_id), channel(ch) {}

    void start()
    {
        while (running)
        {
            if (channel.try_acquire(id))
            {
                channel.log("Node " + std::to_string(id) + "开始传输");
                
                std::this_thread::sleep_for(std::chrono::milliseconds(1));

                channel.release();
                channel.log("Node " + std::to_string(id) + "传输完成");
                break;
            }
            else
            {
                int wait_time = calculate_backoff();
                channel.log("Node " + std::to_string(id) + "退避等待 " + std::to_string(wait_time) + "μs");
                std::this_thread::sleep_for(
                    std::chrono::microseconds(wait_time));
            }
        }
    }

    void stop() { running = false; }
};

int main()
{
    Channel shared_channel;
    NetworkNode node1(1, shared_channel);
    NetworkNode node2(2, shared_channel);

    std::thread t1([&]()
                   { node1.start(); });
    std::thread t2([&]()
                   { node2.start(); });

    t1.join();
    t2.join();
    return 0;
}